/*******************************************************************************
 * SVN­Versioning-Information:
 * ­­­­­­­­­­­­­­­­­­­­­­­­
 * $LastChangedRevision: 137 $
 * $LastChangedBy: CD $
 * $LastChangedDate: 2009-06-30 18:07:22 +0200 (Tue, 30 Jun 2009) $
 * $HeadURL: svn://lvis10.fbm.fht-stuttgart.de/common/Common/src/de/hft_stuttgart/botwar/common/interfaces/IRemotePlayer.java $
 ******************************************************************************/
package de.hft_stuttgart.botwar.common.interfaces;

import de.hft_stuttgart.botwar.common.models.GameInfo;
import de.hft_stuttgart.botwar.common.commands.Cmd;
import de.hft_stuttgart.botwar.common.models.ArmamentInfo;
import de.hft_stuttgart.botwar.common.models.ChassisInfo;
import de.hft_stuttgart.botwar.common.models.MapInfo;
import de.hft_stuttgart.botwar.common.models.NewRobotInfo;
import de.hft_stuttgart.botwar.common.models.PlayerInfo;
import de.hft_stuttgart.botwar.common.models.Position;
import de.hft_stuttgart.botwar.common.models.RobotInfo;
import de.hft_stuttgart.botwar.common.models.ShieldInfo;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.List;

/**
 * Each player gets a reference to his own IRemotePlayer object
 * to start and listen to a game.
 * @author c.a.duevel@gmail.com, pmv-mail@gmx.de
 */
public interface IRemotePlayer extends Remote {

    /**
     * Contains the type of a chat.
     */
    enum CHATTYPE {

        LOBBY,
        GAMELOBBY,
        PRIVATE
    };

    /**
     * Contains the mode of a robot.
     */
    enum MODE {

        STANDARD,
        AGGRESSIVE
    };

    /**
     * Contains the color of a robot.
     */
    enum COLOR {

        BLACK,
        RED,
        GREEN,
        YELLOW,
        BLUE,
        MAGENTA,
        CYAN,
        WHITE
    }

    /**
     * Clients can call this method in order to join a game.
     * @param gameId The Id of the game to join
     * @return Game join successful ?!
     * @throws java.rmi.RemoteException throws RemoteException
     * @throws java.lang.IllegalStateException throws IllegalStateException
     */
    boolean enterGame(Integer gameId) throws RemoteException,
            IllegalStateException;

    /**
     * Returns a List of <code>GameInfo</code> objects about all games.
     * currently initializing and getting played on this server.
     * @return getGameInfos() infos of a game
     * @throws java.rmi.RemoteException throws RemoteException
     */
    List<GameInfo> getGameInfos() throws RemoteException;

    /**
     * Returns the id of a game.
     * @param gameId the id of the game info is requested on
     * @return gameId id of a game
     * @throws java.rmi.RemoteException throws RemoteException
     */
    GameInfo getGameInfo(Integer gameId) throws RemoteException;

    /**
     * Return all commands in a list.
     * @return list of all commands which where issued
     * by the server since the last call, empty list if
     * there are no new commands
     * @throws java.rmi.RemoteException throws RemoteException
     *
     */
    List<Cmd> poll() throws RemoteException;

    /**
     * The client calls this if he is ready to start the game
     * and calls poll() from now on until the end of the game
     * @throws java.rmi.RemoteException throws RemoteException
     * or the game isn't initialized yet.
     */
    void ready() throws RemoteException;

    /**
     * The client calls this method if he has made all the configuration
     * for the game and is ready to prepare the start of the game.
     * @param robotList integer array containing an ordered list of desired bots
     * @throws java.rmi.RemoteException throws RemoteException
     */
    void readyToInit(List<Integer> robotList) throws RemoteException;

    /**
     * Returns the Position of the robot with this ID.
     * @param robotId the id of the robot the position is requested
     * @return robotId id of a robot
     * @throws java.rmi.RemoteException throws RemoteException
     * @throws IllegalStateException If the player is in no game.
     */
    Position getPosition(Integer robotId) throws RemoteException,
            IllegalStateException;

    /**
     * Sets a target.
     * @param robotId The robot to move.
     * @param target The target to move the robot to.
     * @throws java.rmi.RemoteException throws RemoteException
     * @throws java.lang.IllegalStateException If there is no started game yet.
     * @throws java.lang.IllegalArgumentException If there is no robot with this
     * ID or the robot is not owned by this player.
     */
    void setTarget(Integer robotId, Position target) throws
            RemoteException, IllegalStateException, IllegalArgumentException;

    /**
     * Sets the mode of a robot.
     * @param robotId id of the robot.
     * @param mode The mode this robot should use from now on.
     * @throws java.rmi.RemoteException throws RemoteException
     * @throws java.lang.IllegalStateException If there is no started game yet.
     */
    void setMode(Integer robotId, MODE mode) throws RemoteException,
            IllegalStateException;

    /**
     * Is called by the client, if he wants to end the session.
     * @throws java.rmi.RemoteException throws RemoteException
     */
    void logout() throws RemoteException;

    /**
     * Return the id of the created game.
     * @return ID of the created Game
     * @throws java.rmi.RemoteException throws RemoteException
     */
    Integer createGame() throws RemoteException;

    /**
     * The more elaborate Edition of createGame.
     * @param gameName A title for the game, may sth like "metzelstube"
     * @param mapName A string holding a ID for the desired map
     * @param maxPlayers The maxNum of players in this game
     * @param maxBots The maxNum of bots PER player in this game
     * @param maxPlayerLevel The maxPlayerLevel requested for this game
     * @return ID of the created Game
     * @throws java.rmi.RemoteException throws RemoteException
     */
    Integer createGame(String gameName, String mapName, int maxPlayers,
            int maxBots, int maxPlayerLevel) throws RemoteException;

    /**
     * Called by client to send a message to a specific recipient or just
     * yell aloud in the lobby.
     * @param type type of the chat.
     * @param message the mesage
     * @param recipient name of the recipient
     * @throws java.rmi.RemoteException throws RemoteException
     */
    void sendChatMsg(final CHATTYPE type, final String message,
            final String recipient) throws RemoteException;

    /**
     * Called by client to retrieve a complete list of connected players.
     * @return getPlayerInfos list of strings each representing a connected
     * playerid
     * @throws java.rmi.RemoteException throws RemoteException
     */
    List<String> getPlayerInfos() throws RemoteException;

    /**
     * Called by client to retrieve a list of players in gamelobby.
     * @param gameID id of the game
     * @return List<String> A list of strings representing playerids
     * @throws java.rmi.RemoteException throws RemoteException
     */
    List<String> getPlayerInfos(final Integer gameID)
            throws RemoteException;

    /**
     * Called by client to retrieve details about a connected player
     * @param playerID The ID of the player the client wants details about
     * @return getPlayerInfo list of strings each representing a connected
     * playerid
     * @throws java.rmi.RemoteException throws RemoteException
     */
    PlayerInfo getPlayerInfo(String playerID) throws RemoteException;

    /**
     * Returns all information about a saved robot. This method is used to
     * reseive information about robots befor a game until the GameInfo-
     * Object holds the whole RobotInfo about all robots. If the robot
     * is not found, it throws IllegalARgumentException.
     * @param robotID ID of robot the client wants details about.
     * @return RobotInfo of desired robot.
     * @throws java.rmi.RemoteException throws RemoteException
     * @throws IllegalArgumentException
     * @deprecated use the information in GameInfo. Method will be removed.
     */
    @Deprecated
    RobotInfo getRobotInfo(int robotID) throws RemoteException,
            IllegalArgumentException;

    /**
     * Called by client to receive one statisticpage.
     * @param size size from one page
     * @param page the wanted pagenumber
     * @return getRankingPage list of PlayerInfo with all players
     * from the wanted page
     * @throws java.rmi.RemoteException throws RemoteException
     */
    List<PlayerInfo> getRankingPage(int size, int page)
            throws RemoteException;

    /**
     * Called by client for shop.
     * @return list of all available chassises
     * @throws java.rmi.RemoteException throws RemoteException
     */
    List<ChassisInfo> getAvailableChassises() throws RemoteException;

    /**
     * Called by client for shop.
     * @return getAvailableShields list of all available shields
     * @throws java.rmi.RemoteException throws RemoteException
     */
    List<ShieldInfo> getAvailableShields() throws RemoteException;

    /**
     * Called by client for shop
     * @return list of all available armaments
     * @throws java.rmi.RemoteException throws RemoteException
     */
    List<ArmamentInfo> getAvailableArmaments() throws RemoteException;

    /**
     * Called by client for shop and befor gamestart.
     * @return getAvailableRobots list of all available (previous builded)
     * robots from player
     * @throws java.rmi.RemoteException throws RemoteException
     */
    List<RobotInfo> getAvailableRobots() throws RemoteException;

    /**
     * Save a builded robot from player in db.
     * @param robot a builded robot
     * @throws java.rmi.RemoteException throws RemoteException
     */
    void saveRobot(NewRobotInfo robot) throws RemoteException;

    /**
     * Remove a existing robot from this player.
     * @param robotID id from robot
     * @throws java.lang.IllegalArgumentException if the robot does not exist.
     * @throws java.rmi.RemoteException throws RemoteException
     */
    void removeRobot(int robotID) throws
            IllegalArgumentException, RemoteException;

    /**
     * Called by client to retrieve string of player id.
     * @return name of player
     * @throws java.rmi.RemoteException
     */
    String getPlayerID() throws RemoteException;

    /**
     * Called by (game-owner) client to remove a player from gameLobby
     * @param playerID The string representation of the player to be kicked
     * @return Boolean indicating whether kick was successful
     * @throws java.rmi.RemoteException throws RemoteException
     * @throws IllegalStateException If the player is in no game.
     */
    boolean kickPlayer(String playerID) throws RemoteException,
            IllegalStateException;

    /**
     * Called by client to gracefully leave gameLobby
     * @throws java.rmi.RemoteException throws RemoteException
     * @throws IllegalStateException If the player is in no game.
     */
    void leaveGameLobby() throws RemoteException, IllegalStateException;

    /**
     * Called by client to set back to "not ready" when in a game lobby
     * @throws java.rmi.RemoteException throws RemoteException
     * @throws IllegalStateException If the player is in no game.
     */
    void setUnReady() throws RemoteException, IllegalStateException;

    /**
     * Called by client to get a String List of available maps on server.
     * @return getMapInfos infos of a map
     * @throws java.rmi.RemoteException throws RemoteException
     */
    List<String> getMapInfos() throws RemoteException;

    /**
     * Called by client to get a MapInfo Object containing info on a map.
     * @param mapName String representation of map name
     * @return getMapInfo info of a map.
     * @throws java.rmi.RemoteException throws RemoteException
     * @throws IllegalStateException If the player is in no game.
     */
    MapInfo getMapInfo(String mapName) throws RemoteException,
            IllegalStateException;

    /**
     * Called by client to get the needed coins for a level
     * @param playerLevel level for which the amount of coins will be returned
     * @return amount of coins for a level
     * @throws java.rmi.RemoteException throws RemoteException
     */
    long getCoins(int playerLevel) throws RemoteException;

    /**
     * Called by client to get his own amount of coins.
     * @return amount of coins
     * @throws java.rmi.RemoteException throws RemoteException
     */
    long getCoins() throws RemoteException;

    /**
     * Called by client to get his own level.
     * @return own level
     * @throws java.rmi.RemoteException throws RemoteException
     */
    int getLevelRank() throws RemoteException;
}

